<script setup>
import { ref, defineEmits, defineProps } from 'vue';
import { uploadToExternalService } from '../utils/upload';
import { ElMessage } from 'element-plus';
import {
  Picture,
  Microphone,
  Upload,
  Delete
} from '@element-plus/icons-vue';

const props = defineProps({
  type: {
    type: String,
    default: 'image',
    validator: (value) => ['image', 'audio'].includes(value)
  },
  accept: {
    type: String,
    default: 'image/*'
  }
});

const emits = defineEmits(['upload-success', 'upload-error', 'remove']);

const file = ref(null);
const previewUrl = ref('');
const loading = ref(false);
const uploadResult = ref(null);

// 选择文件
const selectFile = () => {
  const fileInput = document.createElement('input');
  fileInput.type = 'file';
  fileInput.accept = props.accept;
  fileInput.style.display = 'none';
  
  fileInput.onchange = async (event) => {
    const selectedFile = event.target.files[0];
    if (selectedFile) {
      file.value = selectedFile;
      
      // 创建预览URL
      if (previewUrl.value) {
        URL.revokeObjectURL(previewUrl.value);
      }
      previewUrl.value = URL.createObjectURL(selectedFile);
      
      // 自动上传
      await uploadSelectedFile();
    }
  };
  
  document.body.appendChild(fileInput);
  fileInput.click();
  document.body.removeChild(fileInput);
};

// 上传选择的文件
const uploadSelectedFile = async () => {
  if (!file.value) {
    ElMessage.warning('请先选择文件');
    return;
  }
  
  try {
    loading.value = true;
    
    // 使用外部服务上传文件
    const result = await uploadToExternalService(file.value);
    
    if (result.success) {
      ElMessage.success('文件上传成功');
      uploadResult.value = result;
      emits('upload-success', {
        fileUrl: result.fileUrl,
        fileName: result.fileName,
        fileType: props.type,
        localUrl: previewUrl.value
      });
    } else {
      ElMessage.error(result.error || '上传失败');
      emits('upload-error', result.error);
    }
  } catch (error) {
    console.error('上传出错:', error);
    ElMessage.error('文件上传出错');
    emits('upload-error', error.message || '上传出错');
  } finally {
    loading.value = false;
  }
};

// 移除已选择的文件
const removeFile = () => {
  if (previewUrl.value) {
    URL.revokeObjectURL(previewUrl.value);
  }
  file.value = null;
  previewUrl.value = '';
  uploadResult.value = null;
  emits('remove');
};
</script>

<template>
  <div class="file-uploader">
    <!-- 文件未选择时显示选择按钮 -->
    <div v-if="!previewUrl" class="uploader-empty" @click="selectFile">
      <el-icon v-if="type === 'image'" class="uploader-icon"><Picture /></el-icon>
      <el-icon v-else class="uploader-icon"><Microphone /></el-icon>
      <div class="uploader-text">
        {{ type === 'image' ? '点击选择图片' : '点击选择音频' }}
      </div>
    </div>
    
    <!-- 文件已选择时显示预览 -->
    <div v-else class="uploader-preview">
      <div class="preview-content">
        <img 
          v-if="type === 'image'" 
          class="preview-image" 
          :src="previewUrl" 
          alt="预览图片" 
        />
        <audio 
          v-else 
          class="preview-audio" 
          :src="previewUrl" 
          controls
        ></audio>
      </div>
      
      <div class="preview-actions">
        <el-button 
          type="danger" 
          circle 
          size="small" 
          @click="removeFile" 
          title="移除文件"
        >
          <el-icon><Delete /></el-icon>
        </el-button>
      </div>
      
      <div v-if="uploadResult" class="upload-info">
        <div class="file-name" :title="uploadResult.fileName">
          {{ uploadResult.fileName }}
        </div>
        <div class="file-url">
          <a :href="uploadResult.fileUrl" target="_blank">查看文件</a>
        </div>
      </div>
    </div>
    
    <!-- 加载中状态 -->
    <div v-if="loading" class="uploader-loading">
      <el-icon class="is-loading"><Upload /></el-icon>
      <span>上传中...</span>
    </div>
  </div>
</template>

<style scoped>
.file-uploader {
  width: 100%;
  position: relative;
}

.uploader-empty {
  border: 2px dashed rgba(255, 182, 193, 0.3);
  border-radius: 12px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s ease;
  background-color: rgba(255, 255, 255, 0.8);
}

.uploader-empty:hover {
  border-color: rgba(255, 182, 193, 0.8);
  background-color: rgba(255, 242, 245, 0.6);
}

.uploader-icon {
  font-size: 32px;
  color: rgba(255, 182, 193, 0.7);
  margin-bottom: 8px;
}

.uploader-text {
  font-size: 14px;
  color: #999;
}

.uploader-preview {
  position: relative;
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 10px;
  box-shadow: 0 4px 12px rgba(255, 182, 193, 0.2);
}

.preview-content {
  width: 100%;
}

.preview-image {
  width: 100%;
  height: auto;
  display: block;
  object-fit: cover;
}

.preview-audio {
  width: 100%;
  margin: 10px 0;
}

.preview-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 10;
}

.uploader-loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.7);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 20;
  backdrop-filter: blur(3px);
  border-radius: 12px;
}

.uploader-loading .el-icon {
  font-size: 32px;
  color: #FFB6C1;
  margin-bottom: 8px;
}

.upload-info {
  background-color: rgba(255, 255, 255, 0.9);
  padding: 10px;
  font-size: 12px;
  overflow: hidden;
}

.file-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 5px;
}

.file-url a {
  color: #409EFF;
  text-decoration: none;
}
</style> 